package com.h2cloud;

import org.springframework.util.PropertyPlaceholderHelper;

import java.util.Properties;

/**
 * @Package: com.h2cloud
 * @ClassName: PropertyPlaceholderHelperDemo
 * @Author: wulongkai
 * @CreateTime: 2023/11/25 11:35
 * @Description:
 */
public class PropertyPlaceholderHelperDemo {
    public static void main(String[] args) {

        // 创建一个PropertyPlaceholderHelper组件，其中：
        // 1. "${"和"}"分别代表占位符的前缀和后缀；此时，表达式"${name}"会被解析为键"name"对应的值
        // 2. ":"代表占位符和默认值的分隔符；如果表达式是"${name:zs}"，且找不到键"name"对应的值，则该表达式会被解析为"zs"
        // 3. true代表忽略无法解析的占位符；在无法解析占位符的情况下，该组件不会抛异常，而是继续往后解析
        PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", ":", true);

        // 先准备好各个属性对应的值
        Properties properties = new Properties();
        properties.setProperty("one", "1");
        properties.setProperty("name1", "zhangsan");
        properties.setProperty("name2", "lisi");

        // 读取键"one"对应的值；这里打印"1"
        System.out.println(helper.replacePlaceholders("${one}", properties));

        // 读取键"two"对应的值；由于找不到该键对应的值，且第四个参数为true，因此不会解析该表达式；这里打印"${two}"
        System.out.println(helper.replacePlaceholders("${two}", properties));

        // 占位符可以嵌套占位符；这里会先将"${one}"解析成"1"，然后解析"${name1}"；这里打印"zhangsan"
        System.out.println(helper.replacePlaceholders("${name${one}}", properties));

        // 占位符可以有默认值；在解析"${two:2}"时，由于找不到键"two"对应的值，因此会将该表达式解析为"2"；这里打印"lisi"
        System.out.println(helper.replacePlaceholders("${name${two:2}}", properties));

        // 默认值还可以是另一个表达式；这里会将"${first:${one}}"解析为${first:1}，因此打印"zhangsan"
        System.out.println(helper.replacePlaceholders("${name${first:${one}}}", properties));

        // 键对应的值也可以是另一个表达式；这里将"${expr}"解析成"${one}"后，还会对"${one}"进行解析；这里打印"1"
        properties.setProperty("expr", "${one}");
        System.out.println(helper.replacePlaceholders("${expr}", properties));

        // 再来个骚操作，通过多个表达式来拼接出另一个表达式，此时是无法解析最终的表达式的；这里打印"${one}"
        properties.setProperty("prefix", "${");
        properties.setProperty("suffix", "}");
        System.out.println(helper.replacePlaceholders("${prefix}one${suffix}", properties));

        // 既然上面的表达式被解析成了"${one}"，那用"${...}"将上面的表达式包起来（如下），能不能最终解析到"1"呢？
        // 答案是不能，因为"${prefix}one${suffix}"被解析成"${one}"后，该组件会直接以"${one}"为键在properties中找对应的值
        // 由于无法找到键"${one}"对应的值，因此解析失败；由于第四个参数为true，因此这里打印"${${prefix}one${suffix}}"
        // 也就是说，通过字符串拼接而得到的占位符表达式是不会被PropertyPlaceholderHelper解析的
        System.out.println(helper.replacePlaceholders("${${prefix}one${suffix}}", properties));

        // 当第四个参数为true时，这里打印"wangwu"；而当第四个参数为false时，这里会抛异常，因为找不到键"three"对应的值
        properties.setProperty("name${three}", "wangwu");
        System.out.println(helper.replacePlaceholders("${name${three}}", properties));
    }
}

